﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace TLL.UTL.Security
{
    public static class Coding
    {
        /// <summary>Coding data by key</summary>
        /// <param name="URLs">Array address</param>
        /// <param name="Key">Coding key</param>
        public static void CodingData(string[] URLs, string Key)
        {
            var coding_data_list = new List<string>();
            foreach (var url in URLs)
                Write(CodingData(GetAll(url), Key), url);
        }
        /// <summary>Return status file (true : coding file, false : encoding file) </summary>
        /// <param name="URLs">Array address file</param>
        public static bool GetStatus(string[] URLs)
        {
            var result = true;
            foreach (var url in URLs)
                result = GetAll(url)[0].Split(new char[] { ' ' })[0] == "Encoding" ? true : false;
            return result;
        }
        /// <summary>Get all lines in file</summary>
        /// <param name="URL">File address</param>
        private static List<string> GetAll(string URL)
        {
            List<string> data_list = new List<string>();
            using (StreamReader reader = new StreamReader(URL, Encoding.UTF8))
            {
                string data_line = string.Empty;
                while ((data_line = reader.ReadLine()) != null)
                    data_list.Add(data_line);
            }
            data_list = data_list.Count != 0 ? data_list : null;
            return data_list;
        }
        /// <summary>Coding/Encoding data</summary>
        /// <param name="Data">Data for coding</param>
        /// <param name="Key">Key coding</param>
        private static List<string> CodingData(List<string> Data, string Key)
        {
            var res = new List<string>();
            if (Data != null)
            {
                if (Data[0] == string.Format("<?xml version={0} encoding={1}?>", "\"1.0\"", "\"utf-8\""))
                {
                    res.Add("Encoding " + CodingLine("Key_Validation_OK", Key));
                    foreach (var line in Data)
                        res.Add(CodingLine(line, Key));
                }
                else
                    foreach (var line in Data)
                        if (line.Split(new char[] { ' ' })[0] != "Encoding")
                            res.Add(CodingLine(line.Split(new char[] { ';' }), Key));
                        else
                            if (CodingLine(line.Split(new char[] { ' ' })[1].Split(new char[] { ';' }), Key) != "Key_Validation_OK")
                                return null;
            }
            else
                res.Add("Encoding " + CodingLine("Key_Validation_OK", Key));
            return res;
        }
        /// <summary>Write to file</summary>
        /// <param name="Data">Data for write</param>
        /// <param name="URL">File address</param>
        private static void Write(List<string> Data, string URL)
        {
            if (Data != null)
                using (var writer = new StreamWriter(URL, false, System.Text.Encoding.UTF8))
                    foreach (var line in Data)
                        writer.WriteLine(line);
        }
        /// <summary>Coding line</summary>
        /// <param name="Line">Text for coding</param>
        /// <param name="Key">Key coding</param>
        private static string CodingLine(string Line, string Key)
        {
            int j = 0;
            var res = string.Empty;
            for (int i = 0; i < Line.Length; i++)
            {
                if (i % (Key.Length) == 0) j = 0;
                res += (Line[i] ^ Key[j]) + ";";
                j++;
            }
            return res;
        }
        /// <summary>Encoding lines</summary>
        /// <param name="Data">Array coding lines</param>
        /// <param name="Key">Key coding</param>
        private static string CodingLine(string[] Lines, string Key)
        {
            int j = 0;
            var res = string.Empty;
            foreach (var line in Lines)
                if (line != string.Empty)
                {
                    if (j > Key.Length - 1) j = 0;
                    res += (char)(int.Parse(line) ^ Key[j]);
                    j++;
                }
            return res;
        }
    }
}
